package org.inspiration.dudu.content.service.impl;

import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import org.inspiration.dudu.common.constant.RedisConstant;
import org.inspiration.dudu.common.util.FileUtil;
import org.inspiration.dudu.common.util.RedisUtil;
import org.inspiration.dudu.content.mapper.QuestionMapper;
import org.inspiration.dudu.content.model.dto.QuestionDTO;
import org.inspiration.dudu.content.model.entity.QuestionEntity;
import org.inspiration.dudu.content.model.vo.QuestionSimpleVO;
import org.inspiration.dudu.content.model.vo.QuestionVO;
import org.inspiration.dudu.content.service.QuestionService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class QuestionServiceImpl implements QuestionService {

    private final QuestionMapper questionMapper;
    private final RedisUtil redisUtil;

    private final RabbitTemplate rabbitTemplate;

    @Value("${dudu.rabbitmq.exchanges.like-exchange.name}")
    private String likeExchangeName;

    @Value("${dudu.rabbitmq.exchanges.like-exchange.queues.question-like-queue.routing-key}")
    private String questionLikeRoutingKey;



    /**
     * 创建问题
     *
     * @param questionEntity 问题实体
     */
    @Override
    public void createQuestion(QuestionEntity questionEntity) {
        questionMapper.createQuestion(questionEntity);
    }

    /**
     * 增加点赞数
     *
     * @param contentId 内容ID
     */
    @Override
    public void increaseLikeCount(String contentId) {
        String key = RedisConstant.QUESTION_KEY_PREFIX + contentId;
        redisUtil.incrementHashFieldWithLua(key, "likeCount");

        // 异步更新数据库
        Map<String, Object> map = new HashMap<>();
        map.put("contentId", contentId);
        map.put("action", "like");
        rabbitTemplate.convertAndSend(likeExchangeName, questionLikeRoutingKey, map);
    }

    /**
     * 减少点赞数
     *
     * @param contentId 内容ID
     */
    @Override
    public void decreaseLikeCount(String contentId) {
        String key = RedisConstant.QUESTION_KEY_PREFIX + contentId;
        redisUtil.decrementHashFieldWithLua(key, "likeCount");

        // 异步更新数据库
        Map<String, Object> map = new HashMap<>();
        map.put("contentId", contentId);
        map.put("action", "unlike");
        rabbitTemplate.convertAndSend(likeExchangeName, questionLikeRoutingKey, map);
    }


    /**
     * 根据内容ID获取用户ID
     *
     * @param contentId 内容ID
     * @return 用户ID
     */
    @Override
    public Long getUserIdByContentId(String contentId) {
        return getQuestionById(contentId).getUserId();
    }

    /**
     * 增加收藏数
     *
     * @param contentId 内容ID
     */
    @Override
    public void increaseFavoriteCount(String contentId) {
        questionMapper.increaseFavoriteCount(contentId);
        String key = RedisConstant.QUESTION_KEY_PREFIX + contentId;
        redisUtil.deleteKey(key);
    }

    /**
     * 减少收藏数
     *
     * @param contentId 内容ID
     */
    @Override
    public void decreaseFavoriteCount(String contentId) {
        questionMapper.decreaseFavoriteCount(contentId);
        String key = RedisConstant.QUESTION_KEY_PREFIX + contentId;
        redisUtil.deleteKey(key);
    }


    /**
     * 将QuestionDTO转换为QuestionEntity
     *
     * @param questionDTO     问题数据传输对象
     * @param contentFilePath 内容文件路径
     * @param uuid            唯一标识
     * @return 转换后的问题实体
     */
    @Override
    public QuestionEntity transToEntity(QuestionDTO questionDTO, String contentFilePath, String uuid) {
        QuestionEntity entity = new QuestionEntity();
        BeanUtils.copyProperties(questionDTO, entity);
        entity.setContentFilePath(contentFilePath);
        entity.setId(uuid);
        return entity;
    }

    /**
     * 根据ID获取问题
     *
     * @param id 问题ID
     * @return 问题视图对象
     */
    @Override
    public QuestionVO getQuestionById(String id) {
        QuestionEntity entity = redisUtil.queryHashCache(
                RedisConstant.QUESTION_KEY_PREFIX,
                id,
                QuestionEntity.class,
                questionMapper::getQuestionById,
                60L,
                TimeUnit.SECONDS
        );
        return transToVO(entity);
    }

    /**
     * 将QuestionEntity转换为QuestionVO
     *
     * @param entity 问题实体
     * @return 转换后的问题视图对象
     */
    @Override
    public QuestionVO transToVO(QuestionEntity entity) {
        QuestionVO questionVO = new QuestionVO();
        BeanUtils.copyProperties(entity, questionVO);
        String content = FileUtil.readStringFromFile(entity.getContentFilePath());
        questionVO.setContent(content);
        return questionVO;
    }

    /**
     * 增加评论数
     *
     * @param contentId 内容ID
     */
    @Override
    public void increaseCommentCount(String contentId) {
        questionMapper.increaseCommentCount(contentId);
        String key = RedisConstant.QUESTION_KEY_PREFIX + contentId;
        redisUtil.deleteKey(key);
    }


    /**
     * 增加回答数
     *
     * @param contentId 内容ID
     */
    @Override
    public void increaseAnswerCount(String contentId) {
        questionMapper.increaseAnswerCount(contentId);
        String key = RedisConstant.QUESTION_KEY_PREFIX + contentId;
        redisUtil.deleteKey(key);
    }

    @Override
    public List<QuestionVO> getQuestionsOrderByDESC(Integer pageNum, Integer pageSize) {
        List<QuestionEntity> list = questionMapper.getQuestionsByDESC((pageNum - 1) * pageSize, pageSize);
        List<QuestionVO> res = new ArrayList<>();
        for(QuestionEntity questionEntity : list) {
            res.add(transToVO(questionEntity));
        }
        return res;
    }

    @Override
    public QuestionSimpleVO transToSimpleVO(QuestionEntity questionEntity) {
        QuestionSimpleVO questionSimpleVO = new QuestionSimpleVO();
        BeanUtils.copyProperties(questionEntity, questionSimpleVO);
        return questionSimpleVO;
    }

    @Override
    public QuestionSimpleVO transToSimpleVO(QuestionVO questionVO) {
        QuestionSimpleVO questionSimpleVO = new QuestionSimpleVO();
        BeanUtils.copyProperties(questionVO, questionSimpleVO);
        return questionSimpleVO;
    }

    @Override
    public List<QuestionVO> getQuestionsByUserIdOrderByDESC(Long userId, Integer pageNum, Integer pageSize) {
        List<QuestionEntity> list = questionMapper.getQuestionsByUserIdOrderByDESC(userId, (pageNum - 1) * pageSize, pageSize);
        List<QuestionVO> res = new ArrayList<>();
        for(QuestionEntity questionEntity : list) {
            res.add(transToVO(questionEntity));
        }
        return res;
    }

}
